/*
 * Powered By XY
 * Since 2020
 */

package com.xy.biz.uc.controller;

import com.xy.biz.uc.client.UserGroupClient;
import com.xy.biz.uc.domain.bo.UserBO;
import com.xy.biz.uc.domain.bo.UserGroupBO;
import com.xy.biz.uc.domain.converter.UserGroupConverter;
import com.xy.biz.uc.domain.dto.UserGroupDTO;
import com.xy.biz.uc.domain.query.UserGroupIdQuery;
import com.xy.biz.uc.domain.query.UserGroupQuery;
import com.xy.biz.uc.domain.req.*;
import com.xy.biz.uc.domain.resp.GetUserGroupResponse;
import com.xy.biz.uc.domain.resp.ListUserGroupItemResponse;
import com.xy.biz.uc.domain.vo.GroupRoleUserTree;
import com.xy.biz.uc.service.UserGroupService;
import com.xy.lang.domain.Page;
import com.xy.lang.domain.Result;
import com.xy.lang.domain.treeing.Tree;
import com.xy.lang.domain.treeing.TreeItem;
import com.xy.lang.util.CollectionUtilsEx;
import com.xy.lang.validation.SaveChecks;
import com.xy.lang.validation.UpdateChecks;
import com.xy.lang.validation.annotation.Validatable;
import com.xy.tool.context.UserContextHolder;
import com.xy.tool.util.BeanUtilsEx;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 *
 *
 * @author zsp
 * @date 2020-8-20
 */
@Slf4j
@RestController
@RequestMapping("/api/uc/user_group")
public class UserGroupController implements UserGroupClient {

	@Autowired
	private UserGroupService userGroupService;

	@Validatable(groups = {SaveChecks.class})
	@PostMapping(value = "/save")
	public Result<?> saveUserGroup(@RequestBody SaveUserGroupRequest request) {
		return userGroupService.saveUserGroup(UserGroupConverter.toBO(request));
	}

	@Validatable(groups = {UpdateChecks.class})
	@PostMapping(value = "/update")
	public Result<?> updateUserGroup(@RequestBody SaveUserGroupRequest request) {
		return userGroupService.updateUserGroup(UserGroupConverter.toBO(request));
	}

	@Validatable
	@PostMapping(value = "/delete")
	public Result<?> deleteUserGroup(@RequestBody GetUserGroupRequest request) {
		return userGroupService.deleteUserGroup(request.getUserGroupId());
	}

	@Override
	@Validatable
	@PostMapping(value = "/get")
	public Result<UserGroupDTO> getUserGroup(@RequestBody GetUserGroupRequest request) {
		return Result.success(UserGroupConverter.toDTO(userGroupService.getUserGroup(UserGroupIdQuery.builder().build().addUserGroupId(request.getUserGroupId()))));
	}

	@Override
	@PostMapping(value = "/list_by_id")
	public Result<List<UserGroupDTO>> listUserGroupByIds(@RequestBody Collection<Long> collection) {
		return Result.success(UserGroupConverter.toDTO(userGroupService.listUserGroupById(UserGroupIdQuery.builder().userGroupIdList(new ArrayList<>(collection)).build())));
	}

	@PostMapping(value = "/list")
	@Override
	public Result<List<UserGroupDTO>> listUserGroup(@RequestBody ListUserGroupRequest request) {
		UserGroupQuery query = UserGroupConverter.toQuery(request);
		return Result.success(toUserGroupDTO(query, userGroupService.listUserGroup(query)));
	}

	@ApiOperation("根据部门名称查部门信息")
	@PostMapping(value = "/list_by_name")
	@Validatable
	public Result<List<GetUserGroupResponse>> listUserGroupByGroupName(@RequestBody ListUserGroupByGroupName request) {
		return Result.success(UserGroupConverter.toResponse(userGroupService.listUserGroupByGroupName(request)));
	}

	@PostMapping(value = "/count")
	public Result<Integer> countUserGroup(@RequestBody ListUserGroupRequest request) {
		return Result.success(userGroupService.countUserGroup(UserGroupConverter.toQuery(request)));
	}

	@PostMapping(value = "/page")
	public Result<Page<UserGroupDTO>> pageUserGroup(@RequestBody ListUserGroupRequest request) {
		UserGroupQuery query = UserGroupConverter.toQuery(request);
		List<UserGroupDTO> list = toUserGroupDTO(query, userGroupService.listUserGroup(query));
		int count = userGroupService.countUserGroup(query);
		return Result.success(new Page<>(list, count));
	}

	@Validatable
	@PostMapping(value = "list_tree_item_for_manage")
	public Result<List<TreeItem>> listDictTreeItemForManage(@RequestBody ListUserGroupItemRequest request) {
		List<ListUserGroupItemResponse> listDictItemResponseList = userGroupService.listUserGroupItem(request);
		if(!CollectionUtils.isEmpty(listDictItemResponseList)) {
			return Result.success(Tree.buildTreeItem(listDictItemResponseList,
					e -> e.getSource().getUserGroupId(),
					e -> e.getSource().getParentUserGroupId(),
					e -> e == null || e == 0,
					e -> e.getUserGroupId().toString(),
					e -> e.getUserGroupName()));
		}
		return Result.success(Collections.emptyList());
	}

	/*@Validatable
	@PostMapping(value = "/list_all_groups")
	public Result<List<ListUserGroupVOResponse>> listAllGroups() {
		List<ListUserGroupItemResponse> groups = userGroupService.listUserGroupItem(ListUserGroupItemRequest.builder().parentUserGroupId(0L).build());
		ArrayList<ListUserGroupVOResponse> listUserGroupVOResponse = new ArrayList<>();
		groups.forEach(
				group -> listUserGroupVOResponse.add(ListUserGroupVOResponse.builder()
				.id(group.getUserGroupId())
				.label(group.getUserGroupName()).build())
		);
		return Result.success(listUserGroupVOResponse);
	}*/

	@Validatable
	@PostMapping(value = "/list_all_groups")
	public Result<GroupRoleUserTree> listAllGroups() {
		GroupRoleUserTree groupRoleUserTree = userGroupService.listGroups();
		return Result.success(groupRoleUserTree);
	}

	private List<UserGroupDTO> toUserGroupDTO(UserGroupQuery query, List<UserGroupBO> userGroupBOList) {
		List<UserGroupDTO> userGroupDTOList = UserGroupConverter.toDTO(userGroupBOList);
		if(query.isWithParent()
				&& !CollectionUtils.isEmpty(userGroupDTOList)) {
			CollectionUtilsEx.foreachSetParent(userGroupDTOList,
					UserGroupDTO::getUserGroupId,
					UserGroupDTO::getParentUserGroupId,
					e -> BeanUtilsEx.copyPropertiesForNewList(
							userGroupBOList.stream()
									.filter(ee -> ee.getParentUserGroup() != null)
									.map(UserGroupBO::getParentUserGroup)
									.collect(Collectors.toSet()),
							() -> new UserGroupDTO()),
					(userGroupDTO, parentUserGroupDTO) -> userGroupDTO.setParentUserGroup(parentUserGroupDTO));
		}
		return userGroupDTOList;
	}

	@Validatable
	@PostMapping(value = "/list_role_id")
	public Result<List<Long>> listRoleIdByUserGroupId(@RequestBody GetUserGroupRequest request) {
		return Result.success(userGroupService.listRoleIdByUserGroupId(request.getUserGroupId()));
	}

	@PostMapping(value = "/list_my")
	@Override
	public Result<List<GetUserGroupResponse>> listMyUserGroup(@RequestBody GetUserGroupByRequest request) {
		return Result.success(userGroupService.listUserGroupBy(UserGroupQuery.builder()
				.userId(UserContextHolder.getUserId())
				.type(request.getType())
				.build()));
	}

	/**
	 * @title listUserGroup
	 * @description 个人的获取所有部门
	 * @date 2021/03/04 13:27:41
	 * @author yuzhenhan
	 * @Return
	 */
	@PostMapping(value = "/list_my_all")
	@Override
	public Result<List<GetUserGroupResponse>> listUserGroup(@RequestBody GetUserGroupByRequest request) {
		return Result.success(userGroupService.listUserGroupBy(UserGroupQuery.max()
				.userId(UserContextHolder.getUserId())
				.build()));
	}

}
